#include "objmodel.h"
#include <iostream>
#include <cstdlib>
#include <vector>
#include <fstream>
#include <cstring>
#include <limits>
#include <cmath>

ObjModel::ObjModel(char *filename)
{
    //Initialization
    has_texture = false;
    radius = 0;
    
    std::ifstream input(filename);
    if(!input)
    {
        std::cerr<<"Unable to open file "<<filename<<std::endl;
        exit(1);
    }

    for(int i = 0; i < 6; ++i)
        boundingBox[i] = 0;
    center[0] = 0, center[1] = 0, center[2] = 0;

    float bmaxX = std::numeric_limits<float>::min(), bmaxY = std::numeric_limits<float>::min(), bmaxZ = std::numeric_limits<float>::min();
    float bminX = std::numeric_limits<float>::max(), bminY = std::numeric_limits<float>::max(), bminZ = std::numeric_limits<float>::max();
    radius = 0;
    
    char buffer[1024] = {0};
    while(input.getline(buffer, 1024))
    {
        //skip commentation line
        if(buffer[0] == '#')
            continue;
        //the vertex line
        else if(strncmp("v ", buffer, 2) == 0)
        {
            float x =0.0f, y = 0.0f, z = 0.0f;
            sscanf(buffer, "v %f %f %f\n", &x, &y, &z);
            vertex.push_back(x);
            vertex.push_back(y);
            vertex.push_back(z);

            bmaxX = bmaxX > x ? bmaxX : x;
            bmaxY = bmaxY > y ? bmaxY : y;
            bmaxZ = bmaxZ > z ? bmaxZ : z;
            bminX = bminX < x ? bminX : x;
            bminY = bminY < y ? bminY : y;
            bminZ = bminZ < z ? bminZ : z;
        }
        //the vertex normal line
        else if(strncmp("vn ", buffer, 3) == 0)
        {
            float u = 0, v = 0, w = 0;
            sscanf(buffer, "vn %f %f %f\n", &u, &v, &w);
            normal.push_back(u);
            normal.push_back(v);
            normal.push_back(w);
        }
        //the face line
        //Be caution! the index in obj file starts at '1', but in OpenGL, it starts at '0'
        else if(buffer[0] == 'f')
        {
            unsigned int f1 = 0, f2 = 0, f3 = 0;
            unsigned int n1 = 0, n2 = 0, n3 = 0;

            sscanf(buffer, "f %i//%i %i//%i %i//%i\n", &f1, &n1, &f2, &n2, &f3, &n3);
            faces_idx.push_back(f1 - 1);
            faces_idx.push_back(f2 - 1);
            faces_idx.push_back(f3 - 1);

            normal_idx.push_back(n1 - 1);
            normal_idx.push_back(n2 - 1);
            normal_idx.push_back(n3 - 1);
        }
        else
            continue;
    }

    boundingBox[0] = bmaxX;
    boundingBox[1] = bmaxY;
    boundingBox[2] = bmaxZ;
    boundingBox[3] = bminX;
    boundingBox[4] = bminY;
    boundingBox[5] = bminZ;

    center[0] = (bmaxX + bminX) * 0.5;
    center[1] = (bmaxY + bminY) * 0.5;
    center[2] = (bmaxZ + bminZ) * 0.5;
    
    radius = sqrt(pow(bmaxX - center[0], 2) + pow(bmaxY - center[1], 2) + pow(bmaxZ - center[2], 2));
    
    input.close();
}
